package com.hll.web.controller;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hll.model.TCoupon;
import com.hll.model.TUser;
import com.hll.model.query.TCouponExample;
import com.hll.model.query.TUserExample;
import com.hll.service.TCouponService;
import com.hll.service.TUserService;
import com.hll.util.JsonUtils;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

//@Api(value = "user", produces = MediaType.APPLICATION_JSON_VALUE)
@RestController
@RequestMapping("/coupon")
public class CouponController {

    @Autowired
    private TCouponService tCouponService;

    @Autowired
    private TUserService tUserService;

    Logger logger = Logger.getLogger(CouponController.class);

    // 我方提供的参数
    private static String msg_sys_id = "896";// 腾瑞明平台id
    private static String client_secret = "061412e4a03c02f9902576ec55ebbe77";// 系统提供的clientSecret。商户密钥key
    private static String AES_key = "061412e4a03c02f9";// 使用标准的AES加密方式，加密解密密钥为卡密系统提供的client_secret前16位英文字符

    private static String proUrl = "http://182.92.119.224:8999/trmoto";

    private static String localUrl = "http://192.168.0.64:8080/trmoto_core";

    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
    /**
     * I1.0 --获取券码分页信息
     * @param json
     * @param request
     * @return
     */
    //	@ApiOperation(value = "pageList", notes = "列表信息", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @RequestMapping(value = "/pageList", method = {RequestMethod.GET, RequestMethod.POST})
    public Object pageList(String json, HttpServletRequest request) {

        int pageNum = 1;
        int pageSize = 10;
        long userid = 0l;
        Map<String, Object> paramMap = JsonUtils.toObject(json, Map.class);
        if (null != paramMap.get("pageNum")) {
            pageNum = Integer.valueOf(paramMap.get("pageNum").toString());
        }
        if (null != paramMap.get("pageSize")) {
            pageSize = Integer.valueOf(paramMap.get("pageSize").toString());
        }
        if (null != paramMap.get("userid") && !"".equals(paramMap.get("userid"))) {
            userid = Long.parseLong(paramMap.get("userid").toString());
        }
        this.is_tb(userid);//查询之前查询券码状态
        TCouponExample example = new TCouponExample();
        example.createCriteria().andUserIdEqualTo(userid);  //券码状态  0-未核销  1-已核销  2-已作废
        example.setOrderByClause("create_time desc");
        example.isDistinct();
        PageHelper.startPage(pageNum, pageSize);
        List<TCoupon> lst = this.tCouponService.selectByExample(example);
        Map<String, Object> map = new HashMap<String, Object>();
        return new PageInfo<TCoupon>(lst);
    }


    /**
     * I2.0 -- 绑定兑换券码
     * @param request
     * @return
     */
    //@ApiOperation(value = "绑定兑换码信息数据", notes = "获取商品信息(用于数据同步)", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @RequestMapping(value = "/bind", method = RequestMethod.POST)
    public Object bind(HttpServletRequest request) {

        JSONObject result = new JSONObject();
        //获取请求参数
        String msg_type = request.getParameter("msg_type");
        String msg_txn_code = request.getParameter("msg_txn_code");
        String msg_sender = request.getParameter("msg_sender");
        String msg_time = request.getParameter("msg_time");
        String msg_sys_sn = request.getParameter("msg_sys_sn");
        String msg_ver = request.getParameter("msg_ver");
        String req_serial_no = request.getParameter("req_serial_no");
        String mobile = request.getParameter("mobile");
        String coupon_no = request.getParameter("coupon_no");
        String coupon_price = request.getParameter("coupon_price");
        String coupon_begintime = request.getParameter("coupon_begintime");
        String coupon_endtime = request.getParameter("coupon_endtime");
        String coupon_desc = request.getParameter("coupon_desc");
        String product_id = request.getParameter("product_id");
        String product_name = request.getParameter("product_name");
        String shop_address = request.getParameter("shop_address");
        String sign = request.getParameter("sign");

        String param_str = msg_type + "&" + msg_txn_code + "&" + msg_sys_id
                + "&" + msg_sender + "&" + msg_time + "&" + msg_sys_sn + "&"
                + msg_ver + "&" + req_serial_no + "&" + mobile + "&"
                + coupon_no + "&" + coupon_price + "&" + coupon_begintime + "&"
                + coupon_endtime + "&" + coupon_desc + "&" + product_id + "&"
                + product_name + "&" + shop_address + "&" + client_secret;
        // 签名方式
        String sign1 = DigestUtils.md5Hex(param_str).toUpperCase();
        if (!sign1.equals(sign)){
            logger.info("***签名失败***");
            result.put("msg_rsp_code" ,"9991");
            result.put("msg_rsp_desc" ,"sign_error");
            return result;
        }
        try {
            //判断手机号是否注册，若没有注册直接创建该用户的账户
            TUserExample tUserExample = new TUserExample();
            tUserExample.createCriteria().andUserNameEqualTo(mobile);
            List<TUser> lst = this.tUserService.selectByExample(tUserExample);
            Long userid = 0l;
            if (lst.size() == 0) {
                TUser tUser = new TUser();
                tUser.setUserName(mobile);
                tUser.setCreateTime(new Date());
                tUser.setModifyTime(new Date());
                this.tUserService.insertSelective(tUser);
                userid = tUser.getId();
            } else {
                userid = lst.get(0).getId();
            }
            String card = Decrypt(coupon_no,AES_key);
            TCouponExample example1= new TCouponExample();
            example1.createCriteria().andCardEqualTo(card);
            List<TCoupon> couponList= this.tCouponService.selectByExample(example1);
            if (couponList.size()>0){
                logger.info("***已绑定***");
                result.put("msg_rsp_code" ,"9992");
                result.put("msg_rsp_desc" ,"card_binded");
                return result;
            }

            //存储兑换券信息到数据库
            TCoupon tCoupon = new TCoupon();
            tCoupon.setUserId(userid);
            tCoupon.setMobile(mobile);
            tCoupon.setCard(Decrypt(coupon_no,AES_key));
            tCoupon.setPrice(Integer.parseInt(coupon_price));
            tCoupon.setProductName(product_name);
            tCoupon.setDescribes(coupon_desc);
            tCoupon.setMsgSysSn(msg_sys_sn);
            tCoupon.setShopAddress(shop_address);
            tCoupon.setCreateTime(new Date());
            tCoupon.setModifyTime(new Date());
            tCoupon.setStatus(0);
            this.tCouponService.insertSelective(tCoupon);
            logger.info("***绑定成功***");
            result.put("msg_rsp_code" ,"0000");
            result.put("msg_rsp_desc" ,"success");
        } catch (Exception e) {
            logger.info("***服务器错误***");
            result.put("msg_rsp_code" ,"9999");
            result.put("msg_rsp_desc" ,"server_error");
        }
        return result;

    }


    public String is_tb(Long userid){
        TCouponExample example = new TCouponExample();
        example.createCriteria().andUserIdEqualTo(userid).andStatusEqualTo(0);  //券码状态  0-未核销  1-已核销  2-已作废
        example.setOrderByClause("create_time desc");
        example.isDistinct();
        List<TCoupon> lsts = this.tCouponService.selectByExample(example);
        String key = "13609560e19c99beba298300435f8725";
        for(TCoupon tCoupon:lsts){
            String code = tCoupon.getCard();
            String result= "";
            //此处传入card，并调用借口验证券码正确性，将返回的信息存入数据库。所以此处要做一个校验，存数据库的动作。存储之后返回校验成功的提示。
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            String time = sdf.format(new Date());
            String mid = "896";
            String action = "chaxun";
            String posId = "hllgzh2017";//好利来公众号
            String shopNo = "hllgzh2017";//好利来公众号
            String version = "1.0.0";//好利来公众号
            String posSeq = time+""+(int)((Math.random()*9+1)*100000);
            String signPara ="action=" + action+ "&code=" + code+"&mid=" + mid   + "&posId="+posId + "&posSeq="+posSeq + "&shopNo=" + shopNo+ "&time=" + time  + "&version="+version + "&key=" + key;
            System.out.println(signPara);
            String _sign = DigestUtils.md5Hex(signPara).toUpperCase();

            System.out.println(_sign);
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("action", action);
            map.put("code", code);
            map.put("time", time);
            map.put("mid", mid);
            map.put("sign", _sign);
            map.put("version", version);
            map.put("shopNo", shopNo);
            map.put("posId", posId);
            map.put("posSeq", posSeq);

            HttpResponse httpResponse = HttpRequest.post(proUrl + "/hexiao2/chaxun.do").
                    form(map).
                    send();

            int httpState = httpResponse.statusCode();
            logger.info("===============调用查询接口，响应状态" + httpState);
            String msg = httpResponse.acceptEncoding("utf-8").bodyText();
            JSONObject resultjson =  JSONObject.parseObject(msg);
            if(null != resultjson && resultjson.containsKey("status") && "1101".equals(resultjson.get("status"))){
                tCoupon.setStatus(1);
                tCouponService.updateByPrimaryKey(tCoupon);
            }
            if(null != resultjson && resultjson.containsKey("status") && "1103".equals(resultjson.get("status"))){
                tCoupon.setStatus(2);
                tCouponService.updateByPrimaryKey(tCoupon);
            }
        }
        return null;
    }



/****************************以下是方法**************************************/

    /**
     * M3.0 标准的AES加密方式
     *
     * @param sSrc
     *            待加密内容
     * @param sKey
     *            加密的密钥
     * @return
     */
    public static String Encrypt(String sSrc, String sKey) throws Exception {
        if (sKey == null) {
            System.out.print("Key为空null");
            return null;
        }
        // 判断Key是否为16位
        if (sKey.length() != 16) {
            System.out.print("Key长度不是16位");
            return null;
        }
        byte[] raw = sKey.getBytes();
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// "算法/模式/补码方式"
        IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes());// 使用CBC模式，需要一个向量iv，可增加加密算法的强度
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
        byte[] encrypted = cipher.doFinal(sSrc.getBytes());

        return new BASE64Encoder().encode(encrypted);// 此处使用BASE64做转码功能，同时能起到2次加密的作用。
    }

    /**
     * M4.0 标准的AES解密方式
     *
     * @param sSrc
     *            待解密内容
     * @param sKey
     *            解密的密钥
     * @return
     */
    public static String Decrypt(String sSrc, String sKey) throws Exception {
        try {
            // 判断Key是否正确
            if (sKey == null) {
                System.out.print("Key为空null");
                return null;
            }
            // 判断Key是否为16位
            if (sKey.length() != 16) {
                System.out.print("Key长度不是16位");
                return null;
            }
            byte[] raw = sKey.getBytes("ASCII");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec(
                    "0102030405060708".getBytes());
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);// 先用base64解密
            try {
                byte[] original = cipher.doFinal(encrypted1);
                String originalString = new String(original);
                return originalString;
            } catch (Exception e) {
                System.out.println(e.toString());
                return null;
            }
        } catch (Exception ex) {
            System.out.println(ex.toString());
            return null;
        }
    }


}
